import {
  IMeshSize,
  NMToolBaseCommand,
  NMToolCmdDialogParams,
} from '@app-nextmesh/types';
import { i18n, nmAppErrorLog } from '@app-nextmesh/common/utils';
import {
  CommandDialog2,
  CommandDialog2Footer,
} from '@app-nextmesh/components/Dialogs';
import {Button, Table, TableProps} from "antd";
import { documentV2 } from '@app-nextmesh/domain';
import React, { useEffect, useState } from 'react';
import {FieldProps, RJSFSchema} from "@rjsf/utils";
import { useProjectStore } from '@app-nextmesh/store/project';
import { updateModelsVisible } from '@app-nextmesh/utils';
import { IChangeEvent } from '@rjsf/core';
import { isArray } from 'lodash';
import {clearField, clearStreamline, renderModels, clearModel, clearMesh} from "@app-nextmesh/utils/renderModel";

interface DataType {
  key: React.Key;
  frame: string;
}

function CmdIsosurfaceDialog({ title, onClose }: NMToolCmdDialogParams) {
  const projectInfo = useProjectStore((state) => state.projectInfo);
  const [formData, setFormData] = useState<IMeshSize>(null);
  const [loading, setLoading] = useState(false);
  const [modelData, setModelData] = useState([]);
  const [solveData, setSolveData] = useState([]);
  const [stepData, setStepData] = useState([]);
  const [fieldData, setFieldData] = useState([]);
  const [variableData, setVariableData] = useState([]);
  const [formatData, setFormatData] = useState([]);
  const [framesData, setFramesData] = useState([]); // 记录帧数据
  const [columnsData, setColumnsData] = useState([]); // 获取表格动态头部

  useEffect(() => {
    clearMesh();
    clearModel();
    // 隐藏场景中的全部几何和网格,方便看结果的网格
    updateModelsVisible('hide');
    if (projectInfo.results.length === 0) {
      return null;
    }
    const modelList: RJSFSchema[] = [];
    projectInfo.results.forEach((item: any) =>
        modelList.push({
          type: 'string',
          title: item.name,
          const: item.uuid,
          taskId: item.taskId,
        }),
    );
    setModelData(modelList);
    initFormData(projectInfo.results[0].uuid);
    return () => {
      clearField();
      clearStreamline();
    }
  }, []);

  const initFormData = (uuid) => {
    documentV2.resultInfo(uuid as string).then((req) => {
      if (req?.solve?.length !== 0) {
        const solve = req?.solve;
        const fieldList = [];
        const stepList = [];
        const variableList = [];
        let framesList = [];
        solve.forEach((item: any) => {
          stepList.push({
            title: item.step.toString(),
            const: item.step,
          });
          if (item.step === 0) {
            item.field.forEach((f) => {
              fieldList.push({
                type: 'string',
                title: f.name,
                const: f.name,
              });
              if (f.type === 'vector' && f.name === item.field[0].name) {
                f.Variable.forEach((v) => {
                  variableList.push({
                    type: 'string',
                    title: v,
                    const: v,
                  });
                });
              }

            });
            setVariableData(variableList);
            setFieldData(fieldList);
            framesList = item.frames.map((item, index) => {
              return { ...item, key: index };
            });
          }
        });
        setSolveData(solve);
        setFramesData(framesList);
        setStepData(stepList);
        initTable(framesList);
        setFormatData([framesList[0].frame])
      }
    });
  };

  const initTable = (framesList) => {
    // 提取所有唯一的字段名作为表头
    const allKeys = framesList.reduce((acc, item) => {
      return [...acc, ...Object.keys(item)];
    }, []);
    // 去重
    const uniqueKeys = [...new Set(allKeys)].filter(
        (item) => item !== 'field_data' && item !== 'key' && item !== 'lsdvmn',
    );
    // 根据字段名生成表头
    const columns = uniqueKeys.map((key: any, index) => ({
      title: key.toUpperCase(), // 使用字段名作为表头
      dataIndex: key, // 数据中的键
      key: key, // 唯一标识
      width: 30,
    }));
    setColumnsData(columns);
  };

  const submit = async (data: any) => {
    // step frame uuid direction field type value
    if (data) {
      const params = {
        step: data.Step,
        frame: formatData[0],
        uuid: data.Model,
        field: data.Field,
        variable: data.Variable,
        value: data.Value
      }
      const req = await documentV2.getPostRenderISOSurface(data.Model, params);
      const modelData = req.isosurface.meshes;
      await renderModels(modelData, false, true);
      setFormData(data);
      setLoading(true);
      try {
        return true;
      } catch (error) {
        nmAppErrorLog('cmd-deformation', 'onSubmit', error);
      } finally {
        setLoading(false);
      }
    }
    return false;
  };
  const onSubmit = async (data) => {
    if (await submit(data)) {
      // onClose();
    }
  };

  const schema: RJSFSchema = {
    type: 'object',
    required: ['Model','Step','Field','Value', 'Variable','Frams'],
    properties: {
      Model: {
        type: 'string',
        title: 'Model',
      },
      Step: {
        type: 'integer',
        title: 'Step',
      },
      Field: {
        type: 'string',
        title: 'Field',
      },
      Value: {
        type: 'number',
        title: 'Value',
      },
      Frams: {
        type: 'array',
        items: { type: 'number' },
      },
    },
  };

  // 处理不同下拉选择业务数据
  const handleResultSelectChange = (data: IChangeEvent, id) => {
    setFormData(null);
    switch (id) {
      case 'root_Model':
        const Model: any = { Model: data.formData.Model };
        setFormData(Model);
        initFormData(data.formData.Model);
        break;
      case 'root_Step':
        const fieldList = [];
        setFormData({
          ...data.formData,
        });
        solveData.forEach((item) => {
          if (item.step === data.formData.Step) {
            item.field.forEach((f) => {
              fieldList.push({
                type: 'string',
                title: f.name,
                const: f.name,
              });
            });
            setFieldData(fieldList);
          }
        });
        break;
      case 'root_Field':
        const params: any = {
          ...formData,
          Field: data.formData.Field,
        };
        delete params?.Variable;
        setFormData({
          ...params,
        });
        const variableList = [];
        setVariableData([]);
        solveData.forEach((item) => {
          if (item.step === data.formData.Step) {
            item.field.forEach((f) => {
              if (f.type === 'vector' && f.name === data.formData.Field) {
                f.Variable.forEach((v) => {
                  variableList.push({
                    type: 'string',
                    title: v,
                    const: v,
                  });
                });
                setVariableData(variableList);
              }
            });
          }
        });
        break;
      case 'root_Variable':
        setFormData({
          ...data.formData,
        });
        break;
      case 'root_Value':
        setFormData({
          ...data.formData,
        });
        break;
    }
  };

  if (modelData.length > 0) {
    const modelObject: any = schema.properties.Model;
    modelObject.oneOf = modelData;
    modelObject.default = modelData[0].const;
  }

  if (stepData.length > 0) {
    const stepObject: any = schema.properties.Step;
    stepObject.oneOf = stepData;
    stepObject.default = stepData[0].const;
  }

  if (fieldData.length > 0) {
    const fieldObject: any = schema.properties.Field;
    fieldObject.oneOf = fieldData;
    fieldObject.default = fieldData[0].const;
  }

  if (isArray(variableData)) {
    if (variableData.length > 0) {
      schema.properties.Variable = {
        type: 'string',
        title: 'Variable',
        oneOf: variableData,
      };
    } else {
      delete schema.properties.Variable;
    }
  }


  const AntTableFieldTemplate = ({}: FieldProps< string[]>) => {
    const rowSelection: TableProps<DataType>['rowSelection'] = {
      type: 'radio', // 设置为 'radio' 实现单选
      selectedRowKeys: formatData,
      onChange: (selectedRowKeys: React.Key[]) => {
        setFormatData(selectedRowKeys)
      },
    };

    return <Table
        rowSelection={rowSelection}
        dataSource={framesData}
        pagination={false}
        columns={columnsData}
        scroll={{ x: 'auto' }}
       />
  }



  // 设置 uiSchema
  const uiSchema = {
    'ui:order': [
      'Model',
      'Step',
      'Field',
      'Variable',
      'Type',
      'Value',
      'X',
      'Y',
      'Z',
      'Frams',
    ],
    Model: {
      'ui:widget': 'select',
    },
    Step: {
      'ui:widget': 'select',
    },
    Field: {
      'ui:widget': 'select',
    },
    Variable: {
      'ui:widget': 'select',
    },
    Frams: {
      'ui:field': AntTableFieldTemplate,
    }
  };

  return (
      <CommandDialog2
          title={title}
          formData={formData}
          schema={schema}
          className='w-[380px]'
          extraUiSchema={uiSchema}
          onSubmit={onSubmit}
          onChange={handleResultSelectChange}
          onClose={onClose}>
        <CommandDialog2Footer>
          <Button
              loading={loading}
              className='w-[100px]'
              type='primary'
              htmlType='submit'>
            {'Apply'}
          </Button>
        </CommandDialog2Footer>
      </CommandDialog2>
  );
}
// 等值面
export const cmdIsosurface: NMToolBaseCommand = {
  id: 'CmdIsosurface',
  label: 'command.draw.isosurface',
  icon: 'commands/simu/isosurface',
  create: (label, onClose) => (
    <CmdIsosurfaceDialog
      title={i18n.t(label)}
      onClose={onClose}
    />
  ),
};
